package uires{

	import flash.display.Bitmap;
	import flash.display.DisplayObject;
	import flash.display.Loader;
	import flash.display.LoaderInfo;
	import flash.display.MovieClip;
	import flash.display.Sprite;
	import flash.events.Event;
	import flash.events.ProgressEvent;
	import flash.net.URLRequest;
	import flash.system.ApplicationDomain;
	import flash.system.LoaderContext;
	import flash.utils.ByteArray;
	
	public class LoginResLoader extends Sprite
	{
		public function LoginResLoader(complete:Function = null, progress:Function = null, error:Function = null) 
		{
			_complete = complete;
			_progress = progress;
			_error = error;
		}

		public function get contentLoaderInfo():LoaderContext {
			return _loadContext;
		}

		public function get isLoadBytes():Boolean {
			return _isLoadBytes;
		}

		public function get finishLoadDate():Date {
			return _finishLoadDate;
		}

		public function get startLoadDate():Date {
			return _startLoadDate;
		}

		public function set autoDispose(bool:Boolean):void 
		{
			_bool = bool;
		}

		public function load(request:URLRequest, context:LoaderContext = null):void 
		{
			_loadContext = context;
			if(_loadContext == null) {
				_loadContext = new LoaderContext(false, new ApplicationDomain(ApplicationDomain.currentDomain));
			}
			if(_stream == null) {
				_stream = new LoginStreamLoader(onStreamComplete, onStreamProgress, onStreamError);
				_stream.load(request);
			}

			_url = request.url;
			_startLoadDate = new Date();
		}

		private function onStreamComplete(stream:LoginStreamLoader):void
		{
			loadBytes(stream.loadContent, _loadContext);
		}

		public function loadBytes(bytes:ByteArray, context:LoaderContext = null):void 
		{
			_loadContext = context;
//			if(_loadContext == null) {
//				_loadContext = new LoaderContext(false, new ApplicationDomain(ApplicationDomain.currentDomain));
//			}
			if(_loader == null) {
				_loader = new Loader();
			} else {
				_loader.unload();
				_loader.unloadAndStop();
			}
			_isLoadBytes = true;
			_loader.contentLoaderInfo.addEventListener(Event.COMPLETE, onComplete);
			_loader.loadBytes(bytes, _loadContext);
		}

		protected function onComplete(e:Event):void 
		{
			_finishLoadDate = new Date();
			_data = (e.target as LoaderInfo).content as DisplayObject;
			removeListener();
			this.addChild(_loader);
			if(_complete != null)
				_complete(this);
			if(_bool)
				dispose();
		}

		protected function onStreamProgress(stream:LoginStreamLoader, e:ProgressEvent):void 
		{
			_totalBytes = e.bytesTotal;
			if(_progress != null)
				_progress(this, e.bytesLoaded, e.bytesTotal);
		}

		protected function onStreamError(e:Event, stream:LoginStreamLoader):void 
		{
			_finishLoadDate = new Date();
			if(_error != null)
				_error(this);
			dispose();
		}

		public function get useTime():int 
		{
			if(_finishLoadDate && _startLoadDate) {
				return _finishLoadDate.getTime() - _startLoadDate.getTime();
			}
			return -1;
		}

		public function get content():DisplayObject 
		{
			return _data;
		}

		private function removeListener():void 
		{
			if(_loader && _loader.contentLoaderInfo) {
				_loader.contentLoaderInfo.removeEventListener(Event.COMPLETE, onComplete);
			}
		}

		public function dispose():void 
		{
			removeListener();
			try {
				if(_stream) {
					_stream.dispose();
				}
				if(_data){
					if(_data is MovieClip) {
						MovieClip(_data).stop();
					}
					else if(_data is Bitmap){
//						BmdUtils.disposeBmd(Bitmap(_data).bitmapData);
						Bitmap(_data).bitmapData = null;
					}
				}
				if(_loader) {
					_loader.close();
					_loader.unload();
					_loader.unloadAndStop();
				}
			} catch(e:Error) {

			}
			_stream = null;
			_loader = null;
			_loadContext = null;
			_data = null;
			_complete = null;
			_progress = null;
			_error = null;
			_bool = true;
			_startLoadDate = null;
			_finishLoadDate = null;
			
		}

		public function get url():String
		{
			return _url;
		}

		private var _loadContext:LoaderContext;
		private var _stream:LoginStreamLoader;
		private var _loader:Loader;
		private var _totalBytes:Number;
		private var _isLoadBytes:Boolean;
		private var _url:String = "";
		private var _bool:Boolean = true;
		private var _data:DisplayObject;
		private var _complete:Function;
		private var _progress:Function;
		private var _error:Function;
		private var _startLoadDate:Date;
		private var _finishLoadDate:Date;
	}
}